from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from vidastream.mycache.models import Cache
import openanything, os, stat, sys, sha, urllib2, re, datetime, feedparser, pytz
utc = pytz.utc

def struct_to_datetime(struct):
	return datetime.datetime(struct[0], struct[1], struct[2], struct[3], struct[4], struct[5], tzinfo=utc)

class FeedManager(models.Manager):
	"""
	helps with the creation of feeds
	"""

				
class Feed(models.Model):
	"""
	Details regarding the feeds being scraped
	"""

	title = models.CharField(maxlength=200)
	slug = models.SlugField(prepopulate_from=("title",))
	url = models.URLField(verify_exists=True, unique=True)
	username = models.CharField(maxlength=30, blank=True)
	password = models.CharField(maxlength=30, blank=True)
	color_mask = models.CharField(maxlength=7, blank=True)
	added = models.DateTimeField('Date Added')
	users = models.ManyToManyField(User)
	disabled = models.BooleanField(default=False)
	disabled_message = models.CharField(maxlength=200, blank=True)
	favicon_url = models.CharField(maxlength=200, default="/media/stream/img/feed_icon.png")

	objects = FeedManager()

	def __str__(self):
		return self.title	

	class Admin:
		pass
	
	def link_exists(self, link):
		try:
			feed_entry = FeedEntry.objects.get(link=link)
		except FeedEntry.DoesNotExist:
			return False
		else:
			return feed_entry

	def guid_exists(self, guid):
		try:
			feed_entry = FeedEntry.objects.get(guid=guid)
		except FeedEntry.DoesNotExist:
			return False
		else:
			return feed_entry

	def update_entries(self):
		print "updating entries"
		print self.url
		cache = Cache()
		cached_feed = cache.cacheIO.get_or_add(self.url)
		parsed_feed = feedparser.parse(cached_feed.path)
		for parsed_entry in parsed_feed.entries:
			feed_entry = self.guid_exists(parsed_entry.id)
			if feed_entry:
				print "found the entry already"
				feed_entry.update(parsed_entry, link=True)
			elif self.link_exists(parsed_entry.id):
				print "found the entry via link"
				feed_entry = link_exists(parsed_entry.id)
				feed_entry.update(parsed_entry)
			else:
				print "making a new entry"
				new_entry = FeedEntry()
				new_entry.create(pared_entry, self)

	def create_feed(self, user=None):
		url = url.encode('utf-8').lower()
		try:
			feed = Feed.objects.get(url=url)
		except Feed.DoesNotExist:
			try:
				parsed_feed = feedparser.parse(url)
			except urllib2.URLError:
				return False
			else:
				if (parsed_feed.status / 100) == 4 or (parsed_feed.status / 100) == 5:
					return False
				elif hasattr(parsed_feed, 'feed') and hasattr(parsed_feed.feed, 'title'):
					self.title = parsed_feed.feed.title
					self.url = url
					self.username = username
					self.password = password

					domain = url.split('/')
					domain = domain[2]

					favicon_url = "http://" + domain + "/favicon.ico"
					try:
						cache_favicon = Cache.cacheIO.get_or_add(favicon_url)
					except IOError:
						pass
					else:
						self.favicon_url = settings.CACHE_PREFIX + cache_favicon.uuid + cache_favicon.file_ext

					Cache.cacheIO.get_or_add(url)

					self.save()
					if user:
						self.users.add(user)

					self.update_entries()
					return new_feed
				else:
					return False
		else:
			if user:
				feed.users.add(user)
			return feed

	def save(self):
		if not self.id:
			self.added = datetime.datetime.now()
		super(Feed, self).save()


class FeedEntry(models.Model):
	"A Feed Entry belongs to a Feed"

	title = models.CharField(maxlength=200)
	content = models.TextField()
	added = models.DateTimeField()
	updated = models.DateTimeField()
	link = models.URLField()
	guid = models.CharField(maxlength=256)
	feed = models.ForeignKey(Feed)

	class Admin:
		pass
	
	def __str__(self):
		return self.feed.title + ": " + self.title
	
	def update(self, parsed_entry, link=False):
		required_attrs = ('title', 'content', 'summary', 'updated')
		for attribute in required_attrs:
			if hasattr(parsed_entry, attribute):
				setattr(self, attribute, parsed_entry.title.encode('utf-8'))
		if link:
			self.link = new_entry.link.encode('utf-8')
		self.save()
	
	def create(self, parsed_entry, feed):
		required_attrs = ('title', 'content', 'summary', 'updated', 'link',)
		for attribute in required_attrs:
			if hasattr(parsed_entry, attribute):
				setattr(self, attribute, parsed_entry.title.encode('utf-8'))
			else:
				raise AttributeError("parsed entry lacks" + attribute + "property")
		self.save()
	
	def save(self):
		if not self.id:
			self.added = datetime.datetime.now()
		super(FeedEntry, self).save()

class FeedPrefs(models.Model):
	"""Extends the Feed model to all for user specified prefrences"""
	user = models.ForeignKey(User)
	feed = models.ForeignKey(Feed)
	title = models.CharField(maxlength=200, default='', blank=True)
	color = models.CharField(maxlength=8, default='', blank=True)
	icon = models.ImageField(upload_to="stream/feed_icons", default="stream/feed_icons/feed_icon.png")
	added = models.DateTimeField()
	disabled = models.BooleanField(default=False)
	username = models.CharField(maxlength=30, default='', blank=True)
	password = models.CharField(maxlength=30, default='', blank=True)

	def __str__(self):
		return self.user.username + ": " + self.feed.title

	def save(self):
		if not self.id:
			self.added = datetime.datetime.now()
		super(FeedPrefs, self).save()

GENDER_CHOICES=(('M', 'Male'),
		('F', 'Female'),
		('O', 'Other'),
		('', ' - '),)

class UserProfile(models.Model):
	"Extends the user model to allow for friends/activation etc."

	user = models.ForeignKey(User, unique=True)
	hidden = models.BooleanField(default=False)
	first_logon = models.BooleanField(default=True)
	friends = models.ManyToManyField(User, related_name='users_befriended', blank=True)
	watching = models.ManyToManyField(User, related_name='users_watching', blank=True)
	added = models.DateTimeField()

	icon = models.ImageField(upload_to="stream/user_icons", default="stream/user_icons/default.png")
	gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
	dob = models.DateField(blank=True, null=True)
	bio = models.TextField(blank=True)
	website = models.URLField(blank=True, null=True)
	country = models.CharField(maxlength=63, blank=True)
	province = models.CharField(maxlength=63, blank=True)
	city = models.CharField(maxlength=63, blank=True)
	postal_code = models.CharField(maxlength=15, blank=True)
	first_name = models.CharField(maxlength=30, blank=True)
	last_name = models.CharField(maxlength=30, blank=True)
	#timezone = models.IntegerField()

	def __str__(self):
		return self.user.username + "_profile"

	class Admin:
		pass

	def save(self):
		if not self.id:
			self.added = datetime.datetime.now()
		super(UserProfile, self).save()
	
	def get_friend(id=None, username=None):
		if username:
			friend = self.friends.get(username=username)
		elif id:
			friend = self.friends.get(id=id)
		else:
			raise self.AttributeError
		return friend

	def remove_friend(id=None, username=None):
		friend = self.get_friend(id=id, username=username)
		self.friends.remove(friend)

	def add_friend(id=None, username=None):
		friend = self.get_friend(id=id, username=username)
		self.friends.add(friend)
		


class BugReport(models.Model):
	def __init__(self, user_id):
		self.user_id = user_id
		self.user = User.objects.get(id=user_id)

	user = models.ForeignKey(User)
	title = models.CharField(maxlength=200)
	report = models.TextField()
	added = models.DateTimeField()

	def save(self):
		if not self.id:
			self.added = datetime.datetime.now()
		super(BugReport, self).save()
	
	class Admin:
		pass
